Skip to content

Market-wide analysis subscription

Production environment: https://stream.valuescan.ai


1. Overview

Market-wide analysis is ValueAgent's synthesized view of BTC/ETH markets using multi-dimensional data. Market subscription is a server-initiated push mechanism: after the user subscribes, when broad-market conditions change, the server pushes analysis text to the client over SSE.


2. Subscription URL

GET https://stream.valuescan.ai/stream/market/subscribe

Authentication parameters (query string):

ParameterTypeRequiredDescription
apiKeystringYesValueScan Access Key
signstringYesHMAC-SHA256 signature
timestamplongYesUnix timestamp in milliseconds
noncestringYesRandom string (replay protection)

Signing algorithm:

sign = HMAC-SHA256(SK, timestampMs + nonce)

Where timestampMs is the millisecond Unix timestamp as a string concatenated with nonce.


3. SSE event format

Connected

event: connected
data: subscribed

Heartbeat (keep-alive)

: heartbeat

event: heartbeat
data: ping

The server sends a heartbeat every 20 seconds.

Market analysis push

event: market
data: {"ts":1775604300144,"uniqueId":"market_analysis_20260408103000","content":"BTC dominates the market with high capital concentration; watch BTC price action."}

market event payload fields:

FieldTypeDescription
tslongPush time (millisecond timestamp)
uniqueIdstringUnique id (for deduplication)
contentstringPlain-text market analysis

4. Subscription examples

Python

python
import hashlib
import hmac
import json
import time
import uuid
import urllib.request
from urllib.parse import urlencode

AK = "your-access-key"
SK = "your-secret-key"

ts = int(time.time() * 1000)
nonce = uuid.uuid4().hex
sign = hmac.new(
    SK.encode(),
    (str(ts) + nonce).encode(),
    hashlib.sha256,
).hexdigest()

params = urlencode({
    "apiKey": AK,
    "sign": sign,
    "timestamp": ts,
    "nonce": nonce,
})

url = f"https://stream.valuescan.ai/stream/market/subscribe?{params}"
req = urllib.request.Request(url, headers={"Accept": "text/event-stream"})

with urllib.request.urlopen(req, timeout=300) as resp:
    event_name = ""
    data_str = ""
    for raw in resp:
        line = raw.decode("utf-8").rstrip("\r\n")

        if line.startswith(":"):
            print("♥ Heartbeat")
            continue

        if line == "":
            if data_str:
                handle_event(event_name, data_str)
            event_name = ""
            data_str = ""
        elif line.startswith("event:"):
            event_name = line[6:].strip()
        elif line.startswith("data:"):
            data_str = line[5:].strip()


def handle_event(event_name: str, data_str: str) -> None:
    if event_name == "connected":
        print(f"[Connected] {data_str}")
    elif event_name == "market":
        payload = json.loads(data_str)
        ts = payload["ts"]
        content = payload["content"]
        dt = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ts / 1000))
        print(f"[Market analysis {dt}] {content}")

cURL (quick check)

bash
python3 -c "
import hashlib, hmac, time, uuid, urllib.parse
SK='your-secret-key'
ts=int(time.time()*1000)
nonce=uuid.uuid4().hex
sign=hmac.new(SK.encode(), (str(ts)+nonce).encode(), hashlib.sha256).hexdigest()
params=urllib.parse.urlencode({'apiKey':'your-access-key','sign':sign,'timestamp':ts,'nonce':nonce})
print(f"curl -N 'https://stream.valuescan.ai/stream/market/subscribe?{params}' -H 'Accept: text/event-stream'")
'"

5. Reconnect on disconnect

Same as signal subscription: use exponential backoff when reconnecting:

python
def listen_with_retry(url: str, max_retries: int = 10) -> None:
    retries = 0
    while retries <= max_retries:
        try:
            req = urllib.request.Request(url, headers={"Accept": "text/event-stream"})
            with urllib.request.urlopen(req, timeout=300) as resp:
                _read_sse(resp)
                break
        except KeyboardInterrupt:
            print("Interrupted by user, exiting.")
            break
        except Exception as e:
            retries += 1
            wait = min(2 ** retries, 60)
            print(f"Connection lost ({e}), reconnect attempt {retries} in {wait}s...")
            time.sleep(wait)
    else:
        print("Max retries reached, exiting.")

6. Error codes

HTTP statusDescription
200Connected successfully
400Missing or invalid parameters
401Signature verification failed or timestamp out of range
404Wrong subscription URL
503Service unavailable (auth backend connection failed)